/*******************************************************************************
 * Copyright (c) 2012, 2017 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution. 
 *
 * The Eclipse Public License is available at 
 *   http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial contribution
 *******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"
#include "cJSON.h"
#define ADDRESS     "tcp://192.168.31.252:1883"
#define SUB_CLIENTID    "ExampleClientSub"
#define PUB_CLIENTID    "ExampleClientPub"
#define SUB_TOPIC       "down"
#define PUB_TOPIC       "up"
#define QOS         1
#define TIMEOUT     10000L

volatile MQTTClient_deliveryToken deliveredtoken;

void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int i;
    char* payloadptr;

    printf("Message arrived\n");
    printf("     topic: %s\n", topicName);
    printf("   message: ");

    payloadptr = message->payload;
    for(i=0; i<message->payloadlen; i++)
    {
        putchar(*payloadptr++);
    }
    putchar('\n');
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}


void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
}

int main(int argc, char* argv[])
{

    cJSON *root=cJSON_CreateObject();
    cJSON_AddItemToObject(root, "name",cJSON_CreateString("zzzfy"));
    cJSON_AddItemToObject(root, "age",cJSON_CreateNumber(24));
    cJSON *msg=cJSON_CreateString(" ");
    cJSON_AddItemToObject(root, "msg",msg);
    //订阅客户端
    MQTTClient client_sub;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    int rc;

    MQTTClient_create(&client_sub, ADDRESS, SUB_CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    //订阅接收
    MQTTClient_setCallbacks(client_sub, NULL, connlost, msgarrvd, delivered);

    if ((rc = MQTTClient_connect(client_sub, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
    printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
           "Press Q<Enter> to quit\n\n", SUB_TOPIC, SUB_CLIENTID, QOS);
    MQTTClient_subscribe(client_sub, SUB_TOPIC, QOS);

    //发布客户端
    MQTTClient client_pub;
    MQTTClient_connectOptions conn_opts2 = MQTTClient_connectOptions_initializer;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;

    MQTTClient_create(&client_pub, ADDRESS, PUB_CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts2.keepAliveInterval = 20;
    conn_opts2.cleansession = 1;

    if ((rc = MQTTClient_connect(client_pub, &conn_opts2)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }

    //发布消息
    char *pub_payload;
    char pub_buffer[1024]={};
    while(1)
    {
        scanf("%s",pub_buffer);
        if(!strcmp(pub_buffer,"Q") || !strcmp(pub_buffer,"q"))
        {
            break;
        }
        //删除节点
        cJSON_DeleteItemFromObject(root,"msg");
        //添加新节点
        cJSON_AddItemToObject(root, "msg",cJSON_CreateString(pub_buffer));
        pub_payload=cJSON_Print(root);

        pubmsg.payload = pub_payload;
        pubmsg.payloadlen = (int)strlen(pub_payload);
        pubmsg.qos = QOS;
        pubmsg.retained = 0;
        MQTTClient_publishMessage(client_pub, PUB_TOPIC, &pubmsg, &token);
        printf("Waiting for up to %d seconds for publication of %s\n"
                "on topic %s for client with ClientID: %s\n",
                (int)(TIMEOUT/1000), pub_payload, PUB_TOPIC, PUB_CLIENTID);
        rc = MQTTClient_waitForCompletion(client_pub, token, TIMEOUT);
        printf("Message with delivery token %d delivered\n", token);
        //判断终端输入的否为q,是的话结束循环
        memset(pub_buffer,0,1024);              
    }

    //结束订阅客户端
   
    return rc;
}
